#pragma once

#include<iostream>
#include<string>
#include<vector>
#include<queue>
#include<unistd.h>
#include"thread.hpp"
#include"log.hpp"
#include"lockGuard.hpp"
const int gNum = 3;
template<class T>
class threadPool
{
public:
    //为了让静态方法routine访问成员属性
    bool empty(){return _taskQueue.empty();}

    pthread_mutex_t* getMutex(){return &lock;}

    void waitCond(){pthread_cond_wait(&cond,&lock);}

    T getTask()
    {
        T t = _taskQueue.front();
        _taskQueue.pop();
        return t;
    }
public:
    threadPool(int defaultNum = gNum)
        :_num(defaultNum)
    {
        pthread_mutex_init(&lock,nullptr);
        pthread_cond_init(&cond,nullptr);

        for(int i=1;i<=_num;i++)
        {
            _threads.push_back(new thread(i,routine,this));
        }
    }
    //启动所有子线程
    void run()
    {
        for(auto& e : _threads)
        {
            e->start();
            // std::cout << e->name() << " 启动成功" << std::endl;
            logMessage(NORMAL, "%s %s", e->name().c_str(), "启动成功");
        }
    }
    //回调函数
    static void* routine(void* args)
    {
        //参数是一个类，类中包含this指针和线程名
        threadData* td = (threadData*)args;
        threadPool<T>* tp =(threadPool<T>*)td->_args;
        //进行处理
        while(true)
        {

            T task;
            {
                lockGuard lockguard(tp->getMutex());

                while(tp->empty())
                {
                    tp->waitCond();
                }
                task = tp->getTask();
            }
            task(td->_name);

        }
    }
    void pushTask(const T &task)
    {
        lockGuard lockguard(&lock);
        _taskQueue.push(task);
        pthread_cond_signal(&cond);
    }
    ~threadPool()
    {
        for (auto &iter : _threads)
        {
            iter->join();
            delete iter;
        }
        pthread_mutex_destroy(&lock);
        pthread_cond_destroy(&cond);
    }
public:

private:
    std::vector<thread*> _threads;//线程数组
    int _num;//线程数量
    std::queue<T> _taskQueue;//任务队列
    pthread_mutex_t lock;//互斥锁
    pthread_cond_t cond;//条件变量
};
